#include <QtGui>
#include <QString>

#include "filemanager.h"
#include "circle.h"
#include "square.h"

#define FILENAME "level.java"

FileManager::FileManager(Scene *scene)
{
    this->scene = scene;    
}

void FileManager::setSpinner(QSpinBox *spinner)
{
    this->spinner = spinner;
}

void FileManager::save()
{
    QFile file(FILENAME);
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&file);

    out << "PuzzleLevel puzzleLevel = new PuzzleLevel(getPlayer(), getFinish(0.5, 1), 10, 5, 3);" << endl;
    out << "Circle circle;" << endl;
    out << "Rectangle rectangle;" << endl << endl;

    int targetsNumber = 1;
    foreach (QGraphicsItem *item, scene->items())
    {
        Element *element = (Element*) item;

        // Skip auxilliary circles and labels.
        if (element->type() == QGraphicsEllipseItem::Type || element->type() == QGraphicsTextItem::Type)
        {
            continue;
        }

        if (element->moveType == PathMove)
        {
            out << "double targets" << targetsNumber << "[] = { ";
            foreach (QGraphicsEllipseItem* node, element->getNodes())
            {
                out << (node->scenePos().x() + NODE_RADIUS) / SCENE_WIDTH << ", ";
                out << (node->scenePos().y() + NODE_RADIUS) / SCENE_HEIGHT << ", ";
            }
            out << "};" << endl;
        }

        out << declaration(element);
        qreal x = element->scenePos().x() / SCENE_WIDTH;
        qreal y = element->scenePos().y() / SCENE_HEIGHT;
        out << x << ", ";
        out << y << ", ";
        out << "new " << MOVE_TYPE_NAME[element->moveType] << "(";
        if (element->moveType == CircleMove)
        {
            qreal radius = element->getMoveCircle()->rect().width() / 2 / SCENE_DIAGONAL;
            out << x << ", " << y << ", " << radius << ", Const.MAX_SPEED, 0";
        }
        else if (element->moveType == FreeMove)
        {
            out << "Const.MAX_SPEED, Const.MAX_SPEED";
        }
        else if (element->moveType == PathMove)
        {
            out << "targets" << targetsNumber++ << ", Const.MAX_SPEED";
        }
        out << "));" << endl;
        out << "puzzleLevel.addEnemy(" << element->toString() << ");" << endl << endl;
    }
    out << "return puzzleLevel;";

    file.close();
}

void FileManager::load()
{
    QFile file(FILENAME);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        return;
    }
    scene->clear();
    QTextStream stream(&file);
    QString line;
    QVector<qreal> *targets = new QVector<qreal>;
    do
    {
        line = stream.readLine();
        QStringList list = line.split(" ");
        if (list[0] == "double")
        {
            for (int i = 4; i < list.size() - 1; i += 2)
            {
                QString universalX = butLast(list[i]);
                QString universalY = butLast(list[i + 1]);
                qreal x = universalX.toDouble() * SCENE_WIDTH;
                qreal y = universalY.toDouble() * SCENE_HEIGHT;
                targets->append(x);
                targets->append(y);
            }
        }
        else if (list.size() > 3 && list[2] == "new")
        {
            QStringList smallList = list[3].split("(");
            QString universalX = butLast(smallList[1]);
            QString universalY = butLast(list[4]);
            qreal x = universalX.toDouble() * SCENE_WIDTH;
            qreal y = universalY.toDouble() * SCENE_HEIGHT;

            if (list[6].contains("CircleMove"))
            {
                QString universalRadius = butLast(list[8]);
                qreal radius = 2 * universalRadius.toDouble() * SCENE_DIAGONAL;
                spinner->setValue(radius);
            }

            for (int i = 0; i < MOVE_TYPE_NAME_SIZE; i++)
            {
                if (list[6].contains(MOVE_TYPE_NAME[i]))
                {
                    scene->moveType = MoveType(i);
                }
            }

            if (list[0].contains("circle"))
            {
                scene->pickCircle();
            }
            else
            {
                scene->pickSquare();
            }

            Element *element = scene->createElement(x, y);
            element->setSelected(false);

            if (list[6].contains("PathMove"))
            {
                for (int i = 0; i < targets->size(); i += 2)
                {
                    element->addNode(targets->at(i), targets->at(i + 1));
                }
                targets->clear();
            }
        }
    }
    while (!line.isNull());

    file.close();
}

QString FileManager::butLast(QString string)
{
    return string.left(string.size() - 1);
}

QString FileManager::declaration(Element *element)
{
    QString name = element->toString();
    return name + " = new " + name[0].toUpper() + name.right(name.size() - 1) + "(";
}
